package cn.fintecher.pangolin.service.business.scheduled;

import cn.fintecher.pangolin.common.enums.*;
import cn.fintecher.pangolin.common.utils.BeanUtils;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.BaseCase;
import cn.fintecher.pangolin.entity.elastic.HistoryCases;
import cn.fintecher.pangolin.entity.mysql.*;
import cn.fintecher.pangolin.service.business.model.RetireCaseModel;
import cn.fintecher.pangolin.service.business.repository.elasticsearch.BaseCaseRespository;
import cn.fintecher.pangolin.service.business.repository.jparepository.AssistCaseRepository;
import cn.fintecher.pangolin.service.business.repository.jparepository.ProcessApplicationRepository;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RetireCaseHandler {

    @Autowired
    private BaseCaseRespository baseCaseRespository;

    @Autowired
    private AssistCaseRepository assistCaseRepository;

    @Autowired
    private ProcessApplicationRepository processApplicationRepository;

    @Async
    public CompletableFuture<RetireCaseModel> retireCaseHandler(List<CaseInfo> caseInfos) {
        RetireCaseModel retireCaseModel = new RetireCaseModel();
        List<HistoryCases> historyCasesArrayList = new ArrayList<>();
        List<String> caseIds = caseInfos.stream().map(CaseInfo::getId).collect(Collectors.toList());
        List<BaseCase> baseCases = Lists.newArrayList(baseCaseRespository.findAllById(caseIds));
        retireCaseModel.setBaseCaseList(baseCases);
        Map<String, BaseCase> baseCaseMap = baseCases.stream().collect(Collectors.toMap(BaseCase::getId, baseCase -> baseCase));
        for (CaseInfo caseInfo : caseInfos) {
            BaseCase baseCase = baseCaseMap.get(caseInfo.getId());
            HistoryCases historyCases = new HistoryCases();
            BeanUtils.copyPropertiesIgnoreNull(baseCase, historyCases);
            historyCases.setHistoryCaseStatus(HistoryCaseStatus.RETIRE_POOL);
            historyCases.setCurrentCollector(caseInfo.getCurrentCollector());
            historyCases.setDepartment(caseInfo.getDepartment());
            historyCases.setOperateTime(ZWDateUtil.getNowDateTime());
            historyCases.setCaseType(caseInfo.getCaseType());
            historyCasesArrayList.add(historyCases);
        }
        List<AssistCase> assistCaseList = Lists.newArrayList(assistCaseRepository.findAll(QAssistCase.assistCase.caseId.in(caseIds)
                .and(QAssistCase.assistCase.assistStatus.eq(AssistStatus.ASSIST_COLLECTING)).or(QAssistCase.assistCase.assistStatus.eq(AssistStatus.ASSIST_WAIT_ASSIGN))));
        assistCaseList.forEach(assistCase -> {
            assistCase.setAssistStatus(AssistStatus.ASSIST_COMPLETED);
        });
        retireCaseModel.setAssistCaseList(assistCaseList);
        List<ProcessApplication> processApplicationList = Lists.newArrayList(processApplicationRepository.findAll(QProcessApplication.processApplication.caseId.in(caseIds).and(QProcessApplication.processApplication.approvalStage.eq(ApprovalStage.WAIT_APPROVAL)
                .or(QProcessApplication.processApplication.approvalStage.eq(ApprovalStage.BEING_APPROVAL)))));
        processApplicationList.forEach(processApplication -> {
            processApplication.setApprovalStage(ApprovalStage.APPROVAL_CANCEL);
            processApplication.getProcessFlowNodes().forEach(processFlowNode -> {
                processFlowNode.setApprovedResult(ApprovalResult.APPROVED_REJECT);
                processFlowNode.setApprovalStatus(ApprovalStatus.APPROVED_COMPLETED);
            });
        });
        retireCaseModel.setProcessApplicationList(processApplicationList);
        retireCaseModel.setHistoryCasesList(historyCasesArrayList);
        return CompletableFuture.completedFuture(retireCaseModel);
    }
}
